package lol.clann.minecraft.springboot.api.bukkit.model;

import lol.clann.minecraft.springboot.api.model.reflect.SetterMethod;
import lombok.Getter;
import lombok.ToString;
import org.bukkit.entity.Projectile;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 *
 * @author pyz
 * @date 2019/6/6 11:32 PM
 */
@Getter
@ToString
public class ProjectileHolder {
    private final String name;
    private final Class<? extends Projectile> type;
    private final Map<String, SetterMethod> propertyMap = new LinkedHashMap<>();

    public ProjectileHolder(Class<? extends Projectile> type) {
        this.type = type;
        this.name = type.getSimpleName().replace("Craft", "");
        initProperty();
    }

    private void initProperty() {
        Method[] ms = ReflectionUtils.getUniqueDeclaredMethods(type);
        for (Method m : ms) {
            if (!Modifier.isPublic(m.getModifiers()) || Modifier.isAbstract(m.getModifiers())) {
                continue;
            }
            if (m.getReturnType() != void.class) {
                continue;
            }
            if (m.getParameterCount() != 1) {
                continue;
            }
            Class propertyClass = m.getParameterTypes()[0];
            if (!ClassUtils.isPrimitiveOrWrapper(propertyClass) && propertyClass != String.class) {
//                过滤掉非基本类型字段
                continue;
            }
            String name = m.getName();
            if (name.length() <= 3 || !name.startsWith("set")) {
                continue;
            }
            name = name.substring(3);
            name = StringUtils.uncapitalize(name);
            propertyMap.put(name, new SetterMethod(m));
        }
        Map<String, SetterMethod> sortMap = new LinkedHashMap<>();
        List<String> properties = new ArrayList<>(propertyMap.keySet());
        properties.sort(String::compareTo);
        for (String property : properties) {
            sortMap.put(property, propertyMap.get(property));
        }
        propertyMap.clear();
        propertyMap.putAll(sortMap);
    }
}
